package jehc.djshi.job.web;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jehc.djshi.common.annotation.Auth;
import jehc.djshi.common.base.BaseAction;
import jehc.djshi.common.base.BaseResult;
import jehc.djshi.common.entity.ScheduleJob;
import jehc.djshi.job.command.JobFactory;
import jehc.djshi.job.model.JobConfig;
import jehc.djshi.job.service.JobConfigService;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @Desc 定时任务配置
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@RestController
@RequestMapping("/xtQuartzSet")
@Api(value = "定时任务配置API",tags = "定时任务配置API",description = "定时任务配置API")
public class JobSetController extends BaseAction {

	@Resource
	private SchedulerFactoryBean schedulerFactoryBean;

	@Resource
	private JobConfigService jobConfigService;

	/**
	 * 加载所有任务
	 * @param model
	 * @return
	 * @throws SchedulerException
	 */
	@ApiOperation(value=" 加载所有任务", notes=" 加载所有任务")
	@PostMapping(value = "/list")
	@Auth(value = "/xtQuartzSet/list",authenticationType = Auth.AuthorizationType.REQUIRED_LOGIN_NOT_AUTH)
	public BaseResult<List<ScheduleJob>> getXtQuartzList(Model model) throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
		List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
		for(JobKey jobKey:jobKeys){
			List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
			for(Trigger trigger : triggers){
				ScheduleJob job = new ScheduleJob();
				job.setJobName(jobKey.getName());
				job.setJobGroup(jobKey.getGroup());
				job.setDesc("触发器:" + trigger.getKey());
				Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
				job.setJobStatus(triggerState.name());
				if(trigger instanceof CronTrigger){
					CronTrigger cronTrigger = (CronTrigger) trigger;
					String cronExpression = cronTrigger.getCronExpression();
					job.setCronExpression(cronExpression);
					jobList.add(job);
				}
			}
		}
		return outItemsStr(jobList);
	}

	/**
	 * 添加一个任务
	 * @param job
	 * @return
	 * @throws IOException
	 * @throws SchedulerException
	 */
	@ApiOperation(value=" 添加一个任务", notes=" 添加一个任务")
	@PostMapping(value = "/add")
	@Auth(value = "/xtQuartzSet/add")
	public BaseResult addXtQuartz(@RequestBody ScheduleJob job) throws IOException, SchedulerException {
		try{
			//一定要紧跟Validate之后写验证结果类
			String seconds = job.getCronExpression();
//			String cronExp = "0/" + seconds + " * * * * ?";
			String cronExp = seconds;
			job.setCronExpression(cronExp);
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
			TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
			//获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			//不存在，创建一个
			if(null == trigger){
				JobDetail jobDetail = JobBuilder.newJob(JobFactory.class).withIdentity(job.getJobName(), job.getJobGroup()).build();
				jobDetail.getJobDataMap().put("scheduleJob", job);
				//表达式调度构建器
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
				//按新的cronExpression表达式构建一个新的trigger
				trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
				scheduler.scheduleJob(jobDetail, trigger);
			}else{
				//Trigger已存在，那么更新相应的定时设置
				//表达式调度构建器
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
				//按新的cronExpression表达式重新构建trigger
				trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
				//按新的trigger重新设置job执行
				scheduler.rescheduleJob(triggerKey, trigger);
			}
			return outAudStr(true);
		}catch(Exception e){
			return outAudStr(false);
		}
	}

	/**
	 * 暂停任务
	 * @param request
	 * @return
	 * @throws SchedulerException
	 */
	@ApiOperation(value=" 暂停任务", notes=" 暂停任务")
	@GetMapping(value = "/stop")
	public BaseResult stopXtQuartz(HttpServletRequest request) throws SchedulerException {
		try{
			String jobGroup = request.getParameter("jobGroup");
			String jobName = request.getParameter("jobName");
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
			scheduler.pauseJob(jobKey);
			return outAudStr(true);
		} catch (Exception e) {
			return outAudStr(false);
		}
	}

	/**
	 * 重启任务
	 * @param jobGroup
	 * @param jobName
	 * @throws SchedulerException
	 */
	@ApiOperation(value=" 重启任务", notes=" 重启任务")
	@GetMapping(value = "/restart")
	public BaseResult reStartXtQuartz(String jobGroup,String jobName) throws SchedulerException {
		try{
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
			scheduler.resumeJob(jobKey);
			return outAudStr(true);
		}catch(Exception e){
			return outAudStr(false);
		}
	}

	/**
	 * 立即执行一次
	 * @param jobGroup
	 * @param jobName
	 * @return
	 * @throws SchedulerException
	 */
	@ApiOperation(value=" 立即执行一次", notes=" 立即执行一次")
	@GetMapping(value = "/start")
	public BaseResult startXtQuartz(String jobGroup,String jobName) throws SchedulerException {
	    try{
	    	Scheduler scheduler = schedulerFactoryBean.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
		    scheduler.triggerJob(jobKey);
			return outAudStr(true);
		}catch(Exception e){
			return outAudStr(false);
		}
	}

	/**
	 * 删除
	 * @param request
	 * @return
	 * @throws SchedulerException
	 */
	@ApiOperation(value=" 删除", notes=" 删除")
	@DeleteMapping(value = "/delete")
	public BaseResult delXtQuartz(HttpServletRequest request) throws SchedulerException {
		try{
			String jobGroup = request.getParameter("jobGroup");
			String jobName = request.getParameter("jobName");
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
			JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
		    scheduler.deleteJob(jobKey);
			return outAudStr(true);
		}catch(Exception e){
			return outAudStr(false);
		}
	}

	/**
	 * 一秒执行一次
	 * @param jobGroup
	 * @param jobName
	 * @return
	 * @throws SchedulerException
	 */
	@ApiOperation(value=" 一秒执行一次", notes=" 一秒执行一次")
	@GetMapping(value = "/onesecond")
	public BaseResult oneSecondXtQuartz(String jobGroup,String jobName) throws SchedulerException {
		try{
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
		    TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
		    //获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
		    CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		    //表达式调度构建器
		    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");
		    //按新的cronExpression表达式重新构建trigger
		    trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
		    //按新的trigger重新设置job执行
		    scheduler.rescheduleJob(triggerKey, trigger);
			return outAudStr(true);
		}catch(Exception e){
			return outAudStr(false);
		}
	}

	/**
	 * 五秒执行一次
	 * @param jobGroup
	 * @param jobName
	 * @return
	 * @throws SchedulerException
	 */
	@ApiOperation(value=" 五秒执行一次", notes=" 五秒执行一次")
	@GetMapping(value = "/fiveseconds")
	public BaseResult fiveSecondsXtQuartz(String jobGroup,String jobName) throws SchedulerException {
		try{
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
		    TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
		    //获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
		    CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		    //表达式调度构建器
		    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
		    //按新的cronExpression表达式重新构建trigger
		    trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
		    //按新的trigger重新设置job执行
		    scheduler.rescheduleJob(triggerKey, trigger);
			return outAudStr(true);
		}catch(Exception e){
			return outAudStr(false);
		}
	}

	/**
	 * 启动默认所有调度任务
	 * @param request
	 */
	@ApiOperation(value=" 启动默认所有调度任务", notes=" 启动默认所有调度任务")
	@GetMapping(value = "/default/start")
	public BaseResult defaultStartXtQuartzSet(HttpServletRequest request){
		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("jobStatus", "NORMAL");
		List<JobConfig> jobConfigList = jobConfigService.getJobConfigListAllByCondition(condition);
		for(int i = 0; i < jobConfigList.size(); i++){
			JobConfig jobConfig = jobConfigList.get(i);
			ScheduleJob job = new ScheduleJob();
			job.setCronExpression(jobConfig.getCronExpression());
			job.setDesc(jobConfig.getDesc_());
			job.setJobGroup(jobConfig.getJobGroup());
			job.setJobId(jobConfig.getJobId());
			job.setJobTitle(jobConfig.getJobTitle());
			job.setJobName(jobConfig.getJobName());
			job.setClientId(jobConfig.getClientId());
			job.setClientGroupId(jobConfig.getClientGroupId());
			job.setJobHandler(jobConfig.getJobHandler());
			job.setJobPara(jobConfig.getJobPara());
			try {
				initQuartz(job);
			} catch (IOException e) {
				return outAudStr(false);
			} catch (SchedulerException e) {
				return outAudStr(false);
			}
		}
		return outAudStr(true);
	}

	/**
	 * 封装
	 * @param job
	 * @throws IOException
	 * @throws SchedulerException
	 */
	public void initQuartz(ScheduleJob job) throws IOException, SchedulerException {
		try{
			//一定要紧跟Validate之后写验证结果类
			String seconds = job.getCronExpression();
			String cronExp = seconds;
			job.setCronExpression(cronExp);
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
			TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
			//获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			//不存在，创建一个
			if(null == trigger){
				JobDetail jobDetail = JobBuilder.newJob(JobFactory.class).withIdentity(job.getJobName(), job.getJobGroup()).build();
				jobDetail.getJobDataMap().put("scheduleJob", job);
				//表达式调度构建器
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
				//按新的cronExpression表达式构建一个新的trigger
				trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
				scheduler.scheduleJob(jobDetail, trigger);
			}else{
				//Trigger已存在，那么更新相应的定时设置
				//表达式调度构建器
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
				//按新的cronExpression表达式重新构建trigger
				trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
				//按新的trigger重新设置job执行
				scheduler.rescheduleJob(triggerKey, trigger);
			}
//			System.out.println("------------------------"+sdf.format(new Date())+"--->初始化启动调度任务成功------------------------------------------");
		}catch(Exception e){
			e.printStackTrace();
//			System.out.println("------------------------"+sdf.format(new Date())+"--->初始化启动调度任务失败------------------------------------------");
		}
	}
}
